package com.zhouxiaoxuan13.promotionservice.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;

/**
 * 负载均衡测试控制器
 * 用于演示和测试Spring Cloud LoadBalancer功能
 */
@Slf4j
@RestController
@RequestMapping("/api/loadbalancer")
@CrossOrigin(originPatterns = "*")
public class LoadBalancerController {

    @Value("${server.port}")
    private String serverPort;

    @Value("${spring.application.name}")
    private String applicationName;

    // 请求计数器
    private static final AtomicLong requestCounter = new AtomicLong(0);

    /**
     * 获取当前服务实例信息
     * 用于测试负载均衡是否正常工作
     */
    @GetMapping("/current-instance")
    public ResponseEntity<Map<String, Object>> getCurrentInstance() {
        Map<String, Object> response = new HashMap<>();
        response.put("serviceName", applicationName);
        response.put("port", serverPort);
        response.put("instanceId", applicationName + ":" + serverPort);
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("requestCount", requestCounter.incrementAndGet());
        response.put("message", "来自端口 " + serverPort + " 的响应");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 获取服务信息（简化版）
     * 兼容测试脚本中的调用
     */
    @GetMapping("/info")
    public ResponseEntity<Map<String, Object>> getInfo() {
        Map<String, Object> response = new HashMap<>();
        response.put("port", serverPort);
        response.put("service", applicationName);
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("requestNumber", requestCounter.incrementAndGet());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 批量测试负载均衡
     * 执行指定次数的调用，返回统计信息
     */
    @GetMapping("/test-batch/{times}")
    public ResponseEntity<Map<String, Object>> testBatch(@PathVariable("times") int times) {
        Map<String, Object> response = new HashMap<>();
        Map<String, Integer> portDistribution = new HashMap<>();
        
        // 模拟批量调用统计
        for (int i = 0; i < times; i++) {
            String currentPort = serverPort;
            portDistribution.put(currentPort, portDistribution.getOrDefault(currentPort, 0) + 1);
        }
        
        response.put("totalRequests", times);
        response.put("currentPort", serverPort);
        response.put("portDistribution", portDistribution);
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("message", "批量测试完成，当前服务端口: " + serverPort);
        
        return ResponseEntity.ok(response);
    }

    /**
     * 获取负载均衡统计信息
     */
    @GetMapping("/stats")
    public ResponseEntity<Map<String, Object>> getStats() {
        Map<String, Object> response = new HashMap<>();
        response.put("serviceName", applicationName);
        response.put("port", serverPort);
        response.put("totalRequests", requestCounter.get());
        response.put("timestamp", LocalDateTime.now().toString());
        response.put("status", "active");
        response.put("loadBalancerType", "Spring Cloud LoadBalancer");
        
        return ResponseEntity.ok(response);
    }

    /**
     * 健康检查端点（用于负载均衡健康检查）
     */
    @GetMapping("/health")
    public ResponseEntity<Map<String, Object>> health() {
        Map<String, Object> response = new HashMap<>();
        response.put("status", "UP");
        response.put("port", serverPort);
        response.put("service", applicationName);
        response.put("timestamp", LocalDateTime.now().toString());

        return ResponseEntity.ok(response);
    }

    // ==================== 熔断器测试接口 ====================

    /**
     * 模拟慢响应（用于测试超时熔断）
     */
    @GetMapping("/slow")
    public ResponseEntity<Map<String, Object>> slowResponse(@RequestParam(value = "delay", defaultValue = "5000") int delay) {
        try {
            log.info("模拟慢响应，延迟: {}ms", delay);
            Thread.sleep(delay);

            Map<String, Object> response = new HashMap<>();
            response.put("message", "慢响应完成");
            response.put("delay", delay + "ms");
            response.put("port", serverPort);
            response.put("timestamp", LocalDateTime.now().toString());

            return ResponseEntity.ok(response);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(Map.of("error", "响应被中断"));
        }
    }

    /**
     * 模拟异常（用于测试异常熔断）
     */
    @GetMapping("/error")
    public ResponseEntity<Map<String, Object>> errorResponse(@RequestParam(value = "errorRate", defaultValue = "50") int errorRate) {
        long requestNum = requestCounter.incrementAndGet();

        // 根据错误率决定是否抛出异常
        if (requestNum % 100 < errorRate) {
            log.error("模拟服务异常，请求号: {}, 错误率: {}%", requestNum, errorRate);
            throw new RuntimeException("模拟的服务异常 - 端口: " + serverPort);
        }

        Map<String, Object> response = new HashMap<>();
        response.put("message", "正常响应");
        response.put("requestNumber", requestNum);
        response.put("port", serverPort);
        response.put("errorRate", errorRate + "%");
        response.put("timestamp", LocalDateTime.now().toString());

        return ResponseEntity.ok(response);
    }

    /**
     * 模拟服务不可用（返回503状态码）
     */
    @GetMapping("/unavailable")
    public ResponseEntity<Map<String, Object>> unavailableResponse() {
        log.warn("模拟服务不可用 - 端口: {}", serverPort);

        Map<String, Object> response = new HashMap<>();
        response.put("error", "服务暂时不可用");
        response.put("port", serverPort);
        response.put("timestamp", LocalDateTime.now().toString());

        return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body(response);
    }

    /**
     * 重置计数器
     */
    @PostMapping("/reset-counter")
    public ResponseEntity<Map<String, Object>> resetCounter() {
        long previousCount = requestCounter.getAndSet(0);
        
        Map<String, Object> response = new HashMap<>();
        response.put("message", "计数器已重置");
        response.put("previousCount", previousCount);
        response.put("currentCount", requestCounter.get());
        response.put("port", serverPort);
        response.put("timestamp", LocalDateTime.now().toString());
        
        return ResponseEntity.ok(response);
    }
}
